#include <glib.h>

static const int thread_num = 3;

static GAsyncQueue *async_queue= NULL;

static gpointer thread_func(gpointer data)
{
    int num = GPOINTER_TO_INT(data);
    g_print("thread %d:  start.....\n", num);
    

    while(1)
    {
        g_print("thread %d: pop job\n", num);

        int job = GPOINTER_TO_INT(g_async_queue_pop(async_queue));
        if (job == -1)
        {
            g_print("thread %d: rx %d\n", num, job);
            break;
        }
        
        g_print("thread %d:  do job %d\n", num, job);
        g_usleep(10);
    }

    g_print("thread %d:  over\n", num);
}


void show_async_queue(void)
{
    GThread *thread[thread_num];

    async_queue = g_async_queue_new();

    for(int i = 0; i< thread_num; i++)
    {
        thread[i] = g_thread_new("worker", thread_func, GINT_TO_POINTER(i));
    }

    for(int i = 1; i< 10; i++)
    {
        g_async_queue_push(async_queue, GINT_TO_POINTER(i));
    }

    for(int i = 0; i< thread_num; i++)
    {
        g_async_queue_push(async_queue, GINT_TO_POINTER(-1));
    }


    for(int i = 0; i< thread_num; i++)
    {
        g_thread_join(thread[i]);
    }


    g_async_queue_unref(async_queue);
}

int main(int argc, char* argv[])
{
    show_async_queue();
    return 0;
}